﻿// 
//    Copyright 2010 The JaernCloud Project
// 
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
// 
//        http://www.apache.org/licenses/LICENSE-2.0
// 
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
// 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JaernCloud.Language.Compiler.Ast {
    
    public abstract class AstExpression : AstTokenInfo {

        public AstExpression() {
            Expressions = new List<AstExpression>();
        }

        public List<AstExpression> Expressions { get; set; }
    }

    public class AstPropertyExpression : AstExpression {
        
        public List<String> PropertyNames { get; set; }
        public AstOperator? Operator { get; set; }

        public AstPropertyExpression() {
            PropertyNames = new List<string>();
        }

        public static AstPropertyExpression FromTagWithClass(string tagWithClass) {
            AstPropertyExpression expr = new AstPropertyExpression();
            expr.PropertyNames.AddRange(tagWithClass.Split('.'));
            return expr;
        }

        public static AstPropertyExpression FromIdent(string ident) {
            AstPropertyExpression expr = new AstPropertyExpression();
            expr.PropertyNames.Add(ident);
            return expr;
        }

        public override string ToString() {
            StringBuilder sb = new StringBuilder();
            foreach (String property in PropertyNames) {
                sb.Append(property);
                sb.Append(".");
            }
            if (sb.Length > 0) {
                sb.Length--;
            }
            if (Operator.HasValue) {
                sb.Append(Operator.Value.AsString());
            }
            return sb.ToString();
        }

    }

    public abstract class AstConstantExpression : AstExpression {

    }

    public class AstNullConstantExpression : AstConstantExpression {

    }

    public class AstStringConstantExpression : AstConstantExpression {
        public String Constant { get; private set; }
        public static AstStringConstantExpression FromToken(Token t) {
            return new AstStringConstantExpression { Constant = AstUtils.ParseToken<String>(t, AstConstantValueKind.String) };
        }
    }

    public class AstFloatConstantExpression : AstConstantExpression {
        public float Constant { get; private set; }
        public static AstFloatConstantExpression FromToken(Token t) {
            return new AstFloatConstantExpression { Constant = AstUtils.ParseToken<float>(t, AstConstantValueKind.Float) };
        }
    }

    public class AstDoubleConstantExpression : AstConstantExpression {
        public double Constant { get; private set; }
        public static AstDoubleConstantExpression FromToken(Token t) {
            return new AstDoubleConstantExpression { Constant = AstUtils.ParseToken<double>(t, AstConstantValueKind.Double) };
        }
    }

    public class AstIntegerConstantExpression : AstConstantExpression {
        public int Constant { get; private set; }
        public static AstIntegerConstantExpression FromToken(Token t) {
            return new AstIntegerConstantExpression { Constant = AstUtils.ParseToken<int>(t, AstConstantValueKind.Integer) };
        }
    }

    public class AstLongConstantExpression : AstConstantExpression {
        public long Constant { get; private set; }
        public static AstLongConstantExpression FromToken(Token t) {
            return new AstLongConstantExpression { Constant = AstUtils.ParseToken<long>(t, AstConstantValueKind.Long) };
        }
    }

    public class AstBooleanConstantExpression : AstConstantExpression {
        public bool Constant { get; private set; }
        public static AstBooleanConstantExpression True {
            get { return new AstBooleanConstantExpression { Constant = true }; }
        }
        public static AstBooleanConstantExpression False {
            get { return new AstBooleanConstantExpression { Constant = false }; }
        }
    }

    public class AstBooleanExpression : AstExpression {

        public AstExpression Left { get; set; }
        public AstExpression Right { get; set; }
        public AstRelationalOperator Operator { get; set; }

    }

}
